package gbackup.core;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

import com.google.gdata.data.docs.DocumentListEntry;

import gbackup.error.NoSuchDirectoryException;
import gbackup.error.NoSuchFileException;

public class RemoteDirectory extends RemoteFile {

	private List<RemoteFile> _childern = null;

	public RemoteDirectory(RemoteDirectory parentDirectory, DocumentListEntry documentListEntry) {
		super(parentDirectory, documentListEntry);
		this._childern = new LinkedList<RemoteFile>();
	}

	public void addChild(RemoteFile child) {
		this._childern.add(child);
	}

	public List<RemoteFile> getChildern() {
		List<RemoteFile> clonedChildern = new ArrayList<RemoteFile>(this._childern.size());
		clonedChildern.addAll(this._childern);
		return clonedChildern;
	}

	@Override
	public boolean isFile() {
		return false;
	}

	@Override
	public boolean isDirectory() {
		return true;
	}

	public RemoteDirectory getDirectoryByPath(String path) throws NoSuchDirectoryException {
		try {
			RemoteFile rf = this._getFileByPath(path);
			if (!rf.isDirectory())
				throw new NoSuchDirectoryException(path);
			else
				return (RemoteDirectory) rf;
		} catch (NoSuchFileException nsde) {
			throw new NoSuchDirectoryException(path);
		}
	}

	public RemoteFile getFileByPath(String path) throws NoSuchFileException {
		try {
			RemoteFile rf = this._getFileByPath(path);
			if (!rf.isFile())
				throw new NoSuchFileException(path);
			else
				return (RemoteDirectory) rf;
		} catch (NoSuchFileException nsde) {
			throw new NoSuchFileException(path);
		}
	}

	private RemoteFile _getFileByPath(String path) throws NoSuchFileException {
		RemoteDirectory workingDirectory = this;
		if (path.startsWith(RemoteFile.rootDirectoryNotation)) {
			/* find the root directory */
			while (workingDirectory.getParent() != null)
				workingDirectory = workingDirectory.getParent();
		}

		StringTokenizer st = new StringTokenizer(path, RemoteFile.pathSeperator);
		while (st.hasMoreTokens()) {
			String p = st.nextToken();

			if (p.equals(RemoteFile.parentDirectoryNotation)) {
				if (workingDirectory.getParent() != null)
					workingDirectory = workingDirectory.getParent();
				continue;
			} else if (p.equals(RemoteFile.currentDirectoryNotation)) {
				continue;
			}

			boolean found = false;
			for (RemoteFile rf : workingDirectory.getChildern()) {
				if (rf.getName().equals(p) && !st.hasMoreTokens())
					return rf;
				if (rf.getName().equals(p) && st.hasMoreTokens() && rf.isDirectory()) {
					workingDirectory = (RemoteDirectory) rf;
					found = true;
					break;
				}
			}
			if (!found) {
				throw new NoSuchFileException(p);
			}
		}

		/* never reachable */
		return workingDirectory;
	}
}
